/*
 * (c) 2007, Delsi Interactive
 * User: ChRoNo
 * Date: 16/04/2007
 * Time: 09:44 p.m.
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Threading;

namespace CSE
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		/*
		 * Constants
		 */
		public static readonly int EDIT_NONE            = -1;
		public static readonly int EDIT_CLIP_BITMAP     = 0;
		public static readonly int EDIT_CLIP_STATIC     = 1;
		public static readonly int EDIT_CLIP_ANIMATION  = 2;
		
		public static readonly int DRAG_NONE = 0;
		public static readonly int DRAG_ALL = 1;
		public static readonly int DRAG_LEFT = 2;
		public static readonly int DRAG_RIGHT = 3;
		public static readonly int DRAG_UP = 4;
		public static readonly int DRAG_DOWN = 5;
		public static readonly int DRAG_STAGE = 6;
		
	    /*
	     * Variables
	     */
	    public static MainForm self = null;
	    public static NewClip nc = null;
	    public static GetClips gc = null;
	    
	    public static TimeLine tl = null;
	    
	    public static TreeView TreeView = null;
	    public static TreeNodeCollection libAbs = null;
	    public static TreeNode libClipsRoot = null;
	    public static TreeNode libClipsLibrary = null;
	    public static TreeNode libBitmap = null;
	    public static TreeNode libSel = null;
	    public static TreeNode libEdit = null;
	    public static TreeNode libDragDrop = null;
	    
	    // Thread PreviewThread = null;
	    
	    private int EditType = EDIT_NONE;
	    private int EditClip = -1;
	    
	    private int DragType = DRAG_NONE;
	    private int DragOX = 0;
	    private int DragOY = 0;
	    private int DragTemp = 0;
	    
	    [STAThread]
		public static void Main(string[] args)
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new MainForm());
		}
		
		public MainForm()
		{
			InitializeComponent();
			self = this;
			tl = this.timeLine;
			TreeView = this.treeLibrary;
			this.DoubleBuffered = true;
			
			/*
			PreviewThread = new Thread(new ThreadStart(PreviewModeThread));
			PreviewThread.IsBackground = true;
            PreviewThread.Start();
            */
			
			MainFormSetDefaults();
		}
		
		/*
		private void PreviewModeThread ()
		{
		    DateTime starttime = DateTime.Now;
		    
		    while(true)
		    {
		        Application.DoEvents();
		        
		        if (starttime.Second == DateTime.Now.Second)
		        {
		            continue;
		        }
		        
		        this.picStage.Invalidate();
		    }
		}
		*/
		
		/*
		 * MainFormLoad
		 */
		public void MainFormLoad(object sender, EventArgs e)
		{
			this.spriteToolStripMenuItem.Visible = false;
		}
		
		/*
		 * MainFormClose
		 */
		public void MainFormClose (object sender, EventArgs e)
		{
		    // PreviewThread.Abort();
		}
		
		/*
		 * MainFormResize
		 */
		public void MainFormResize(object sender, EventArgs e)
		{
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
		}
		
		/*
		 * MainFormActivated
		 */
		public void MainFormActivated (object sender, EventArgs e)
		{
			/*if (gc != null)
			{
				this.Show(
			}*/
		}
		
		/*
		 * MainFormSetDefaults
		 */
		public void MainFormSetDefaults ()
		{
		    this.cboZoom.Text = "100%";
			this.tipPos.Text = "";
			PropertiesShow(false);
			
			this.lblClipName.Text = Workspace.CLIP_NAME_NONAME;
			
			libSel = null;
			libEdit = null;
			
			if (Workspace.type == Workspace.TYPE_SPRITE)
			{
				this.spriteToolStripMenuItem.Visible = true;
				
				this.cboZoom.Enabled = true;
				this.tcStage.Enabled = false;
				
				CreateSpriteLibrary();
			}
			else
			{
				this.cboZoom.Enabled = false;
				this.tcStage.Enabled = false;
			}
		}
		
		/*
		 * PropertiesShow
		 */
		void PropertiesShow (bool sw)
		{
		    if (!sw)
		    {
		        this.txtPropName.Text = "";
		        this.txtX.Text = "";
			    this.txtY.Text = "";
			    this.txtW.Text = "";
			    this.txtH.Text = "";
		    }
		    
		    this.txtPropName.Visible = sw;
		    this.lblName.Visible = sw;
		    
		    this.txtX.Visible = sw;
		    this.txtY.Visible = sw;
		    this.txtW.Visible = sw;
		    this.txtH.Visible = sw;
		    
		    this.lblX.Visible = sw;
		    this.lblY.Visible = sw;
		    this.lblW.Visible = sw;
		    this.lblH.Visible = sw;
		}
		
		/*
		 * CreateSpriteLibrary
		 */
		private void CreateSpriteLibrary ()
		{
			ImageList myImageList = new ImageList();
			myImageList.Images.Add(Utils.LoadBitmapResource("clip.Bitmap"));
			myImageList.Images.Add(Utils.LoadBitmapResource("animclip.Bitmap"));
		    myImageList.Images.Add(Utils.LoadBitmapResource("bitmap.Bitmap"));
		    myImageList.Images.Add(Utils.LoadBitmapResource("folder.Bitmap"));
		    
		    this.treeLibrary.ImageList = myImageList;
		    this.treeLibrary.ImageIndex = 0;
		    
		    libAbs = this.treeLibrary.Nodes;
		    
		    libClipsRoot = this.treeLibrary.Nodes.Add(Workspace.GetKey().ToString() + "_clip", "_root", 1, 1);
		    libClipsLibrary = this.treeLibrary.Nodes.Add(Workspace.GetKey().ToString() + "_library", "Library", 3, 3);
		    libBitmap = this.treeLibrary.Nodes.Add("_bitmap", "Bitmap", 2, 2);
		    
		    libBitmap.Nodes.Add("_bitmap_source", "(null)", 2, 2);
		}
		
		/*
		 * UpdateCurrentEditClip
		 */
		public void UpdateCurrentEditClip (Clip _clip)
		{
		    int i = 0;
		    int l = 0;
		    
		    this.timeLine.Clear();
		    
		    for (i=0; i<_clip.childs.Count; i++)
		    {
		        l = this.timeLine.AddLayer(_clip.childs[i].name);
		        this.timeLine.AddKeyframe(l, _clip.childs[i].start, TimeLine.KEYFRAME_START);
		    }
		    
		    _clip.AdjustSize();
		    
		    if (_clip.type == Workspace.TYPE_ANIMCLIP)
		    {
		        this.timeLine.guide_index = this.timeLine.timeline_middle + ((_clip.childs.Count) * TimeLine.KEYFRAME_WIDTH);
		    }
		    
		    this.picStage.Invalidate();
		    this.timeLine.Invalidate();
		}
		
		/*
		 * AppendClip
		 */
		public void AppendClip (Clip _parent, Clip _child, int x, int y)
		{
		    if (_parent.usebitmap)
		    {
		        Utils.MsgBox("Can't add clips here!");
		        return;
		    }
		    
		    if (_parent.type == Workspace.TYPE_ANIMCLIP)
		    {
		    	_parent.childs.Add(new ClipChild(x,y,_child.name, _parent.childs.Count, _parent.childs.Count));
		    }
		    else
		    {
		    	_parent.childs.Add(new ClipChild(x,y,_child.name, 0, 0));
		    }
		    UpdateCurrentEditClip(_parent);
		}
		
		/*
		 * File/New
		 */
		void NewToolStripMenuItemClick(object sender, EventArgs e)
		{
		    if (MainForm.libAbs != null)
		    {
		        MainForm.libAbs.Clear();
		    }
		    
		    Workspace.Shutdown();
		    Workspace.Init();
		    
		    this.picStage.Invalidate();
		    this.picPreview.Invalidate();
		}
		
		/*
		 * File/Load
		 */
		void LoadToolStripMenuItemClick(object sender, EventArgs e)
		{
			OpenFileDialog ofdSprite = new OpenFileDialog();
            ofdSprite.Filter = "Sprite Files |*.cse";
            ofdSprite.Multiselect = false;
            
            if (ofdSprite.ShowDialog() == DialogResult.OK)
            {
            	Workspace.Shutdown();
            	Workspace.Init();
            	Workspace.SetPath(ofdSprite.FileName.Substring(0,ofdSprite.FileName.LastIndexOf('\\') + 1));
            	Workspace.Load(ofdSprite.FileName);
            	this.picStage.Invalidate();
            	this.picPreview.Invalidate();
            }
		}
		
		/*
		 * File/Save
		 */
		void SaveToolStripMenuItemClick(object sender, EventArgs e)
		{
			if (Workspace.type == Workspace.TYPE_NONE)
			{
				return;
			}
			
			SaveFileDialog sfdSprite = new SaveFileDialog();
            sfdSprite.Filter = "Sprite Files |*.cse";
            
            if (sfdSprite.ShowDialog() == DialogResult.OK)
            {
                Workspace.SetPath(sfdSprite.FileName.Substring(0,sfdSprite.FileName.LastIndexOf('\\') + 1));
            	Workspace.Save(sfdSprite.FileName);
            	this.picStage.Invalidate();
            	this.picPreview.Invalidate();
            }
		}
		
		/*
		 * File/Export/Sprite (XML)
		 */
		void SpriteXMLToolStripMenuItemClick(object sender, EventArgs e)
		{
			SaveFileDialog sfdSprite = new SaveFileDialog();
            sfdSprite.Filter = "XML Files |*.xml";
            
            if (sfdSprite.ShowDialog() == DialogResult.OK)
            {
            	Workspace.ExportXML(sfdSprite.FileName);
            }
		}
		
		/*
		 * File/Preferences
		 */
		void PreferencesToolStripMenuItemClick(object sender, EventArgs e)
		{
			
		}
		
        /*
		 * Sprite/Insert new clip
		 */
		void InsertNewClipToolStripMenuItemClick(object sender, EventArgs e)
		{
		    libSel = MainForm.libClipsLibrary;
			nc = new NewClip();
		}

		/*
		 * Sprite/Get clips
		 */
		void GetClipsToolStripMenuItemClick(object sender, EventArgs e)
		{
			if (Workspace.type == Workspace.TYPE_NONE
			|| Workspace.bitmap == null)
			{
				Utils.MsgBox("Import a bitmap first!");
				return;
			}
			
			gc = new GetClips();
		}

		/*
		 * Sprite/Set source image
		 */
		void SetSourceImageToolStripMenuItemClick(object sender, EventArgs e)
		{
			OpenFileDialog ofdSprite = new OpenFileDialog();
            ofdSprite.Filter = "Image Files |*.png;*.bmp;*.tga;*.pcx";
            ofdSprite.Multiselect = false;
            
            if (ofdSprite.ShowDialog() == DialogResult.OK)
            {
                Workspace.SetPath(ofdSprite.FileName.Substring(0,ofdSprite.FileName.LastIndexOf('\\') + 1));
                Workspace.SetSourceBitmap(ofdSprite.FileName.Substring(ofdSprite.FileName.LastIndexOf('\\') + 1));
            	libBitmap.Nodes.Clear();
            	libBitmap.Nodes.Add("_bitmap_source", Workspace.bitmap_path, 2, 2);
            }
		}
		
		/*
		 * PicPreviewPaint
		 */
		void PicPreviewPaint(object sender, PaintEventArgs e)
		{
		    Stage.DrawPreview(e.Graphics, this.picPreview.Width, this.picPreview.Height);
		}
		
		/*
		 * PicStagePaint
		 */
		void PicStage_Paint(object sender, PaintEventArgs e)
		{
		    Stage.Draw(e.Graphics, this.picStage.Width, this.picStage.Height);
		}
		
		/*
		 * PicStage_MouseWheel
		 */
		void PicStage_MouseWheel (object sender, MouseEventArgs e)
		{
		    // Update the drawing based upon the mouse wheel scrolling.
		    int numberOfTextLinesToMove = Utils.Sign(e.Delta);
            
            if (numberOfTextLinesToMove != 0)
            {
                int zoom = Stage.zoom + numberOfTextLinesToMove;
			    
                if (zoom < 1)
			    {
				    zoom = 1;
			    }
			    else if (zoom > 10)
			    {
    				zoom = 10;
			    }
			
			    this.cboZoom.Text = (zoom * 100).ToString() + "%";
			    Stage.zoom = zoom;
			    this.picStage.Invalidate();
            }
		}
		
		/*
		 * PicStageMouseDown
		 */
		void PicStage_MouseDown (object sender, MouseEventArgs e)
		{
			DragType = DRAG_NONE;
			EditClip = -1;
			this.picStage.Cursor = System.Windows.Forms.Cursors.Default;
			int x = Stage.GetPixelsX(e.X, this.picStage.Width);
			int y = Stage.GetPixelsY(e.Y, this.picStage.Height);
			
			/*
			 * Stage drag
			 */
			if (e.Button == MouseButtons.Right)
			{
			    DragType = DRAG_STAGE;
			    DragOX = e.X;
			    DragOY = e.Y;
			}
			
			/*
			 * EDIT_CLIP_BITMAP
			 */
			if (EditType == EDIT_CLIP_BITMAP)
			{
    			if (e.Button == MouseButtons.Left)
    			{
        			if (libEdit == null)
        			{
        				return;
        			}
        			
        			Rectangle r_center = new Rectangle(((Clip)libEdit.Tag).r.X + 2,
        			                            ((Clip)libEdit.Tag).r.Y + 2,
        			                            ((Clip)libEdit.Tag).r.Width - 3,
        			                            ((Clip)libEdit.Tag).r.Height - 4);
        			
        			Rectangle r_left = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
        			                            ((Clip)libEdit.Tag).r.Y - 1,
        			                            3,
        			                            ((Clip)libEdit.Tag).r.Height + 2);
        			
        			Rectangle r_right = new Rectangle((((Clip)libEdit.Tag).r.X + ((Clip)libEdit.Tag).r.Width ) - 1,
        			                            ((Clip)libEdit.Tag).r.Y - 1,
        			                            3,
        			                            ((Clip)libEdit.Tag).r.Height + 2);
        			
        			Rectangle r_up = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
        			                            ((Clip)libEdit.Tag).r.Y - 1,
        			                            ((Clip)libEdit.Tag).r.Width + 2,
        			                            3);
        			
        			Rectangle r_down = new Rectangle(((Clip)libEdit.Tag).r.X - 1,
        			                            (((Clip)libEdit.Tag).r.Y + ((Clip)libEdit.Tag).r.Height) - 2,
        			                            ((Clip)libEdit.Tag).r.Width + 2,
        			                            3);
        			
        			if (r_center.Contains(x, y))
        			{
        				DragType = DRAG_ALL;
        				DragOX = x - (((Clip)libEdit.Tag).r.X);
        				DragOY = y - (((Clip)libEdit.Tag).r.Y);
        				this.picStage.Cursor = System.Windows.Forms.Cursors.NoMove2D;
        			}
        			else if (r_left.Contains(x, y))
        			{
        				DragType = DRAG_LEFT;
        				DragOX = x;
        				DragTemp = ((Clip)libEdit.Tag).r.Width;
        				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeWE;
        			}
        			else if (r_right.Contains(x, y))
        			{
        				DragType = DRAG_RIGHT;
        				DragOX = x;
        				DragTemp = ((Clip)libEdit.Tag).r.Width;
        				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeWE;
        			}
        			else if (r_up.Contains(x, y))
        			{
        				DragType = DRAG_UP;
        				DragOY = y;
        				DragTemp = ((Clip)libEdit.Tag).r.Height;
        				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeNS;
        			}
        			else if (r_down.Contains(x, y))
        			{
        				DragType = DRAG_DOWN;
        				DragOY = y;
        				DragTemp = ((Clip)libEdit.Tag).r.Height;
        				this.picStage.Cursor = System.Windows.Forms.Cursors.SizeNS;
        			}
    			}
			}
			/*
			 * EDIT_CLIP_STATIC
			 */
			else if (EditType == EDIT_CLIP_STATIC)
			{
			    if (e.Button == MouseButtons.Left)
    			{
			        int i=0;
			        Clip _clip = ((Clip)libEdit.Tag);
			        
			        for (i=_clip.childs.Count - 1; i>-1; i--)
			        {
			            Clip _child = Workspace.GetClipFromName(_clip.childs[i].name);
			            
			            Rectangle r = new Rectangle(_clip.childs[i].x,
        			                                _clip.childs[i].y,
        			                                _child.r.Width,
        			                                _child.r.Height);
			            
			            if (r.Contains(x, y))
			            {
			            	MainForm.self.timeLine.mouse_y = (i * TimeLine.LAYER_HEIGHT) + TimeLine.LAYER_HEIGHT;
			            	MainForm.self.timeLine.Invalidate();
			            	
			                EditClip = i;
                            DragType = DRAG_ALL;
			                DragOX = x - _clip.childs[i].x;
        				    DragOY = y - _clip.childs[i].y;
			                break;
			            }
			        }
			    }
			}
			/*
			 * EDIT_CLIP_ANIMATION
			 */
			else if (EditType == EDIT_CLIP_ANIMATION)
			{
			    if (e.Button == MouseButtons.Left)
    			{
			        int i=0;
			        Clip _clip = ((Clip)libEdit.Tag);
			        
			        for (i=_clip.childs.Count - 1; i>-1; i--)
			        {
			            if (i != this.timeLine.guide_index)
			            {
			                continue;
			            }
			            
			            Clip _child = Workspace.GetClipFromName(_clip.childs[i].name);
			            
			            Rectangle r = new Rectangle(_clip.childs[i].x,
        			                                _clip.childs[i].y,
        			                                _child.r.Width,
        			                                _child.r.Height);
			            
			            if (r.Contains(x, y))
			            {
			            	MainForm.self.timeLine.mouse_y = (i * TimeLine.LAYER_HEIGHT) + TimeLine.LAYER_HEIGHT;
			            	MainForm.self.timeLine.guide_index = i * TimeLine.KEYFRAME_WIDTH;
			            	MainForm.self.timeLine.Invalidate();
			            	
			                EditClip = i;
                            DragType = DRAG_ALL;
			                DragOX = x - _clip.childs[i].x;
        				    DragOY = y - _clip.childs[i].y;
			                break;
			            }
			        }
			    }
			}
		}
		
		/*
		 * PicStageMouseMove
		 */
		void PicStage_MouseMove (object sender, MouseEventArgs e)
		{
			if (Workspace.type == Workspace.TYPE_NONE)
			{
				return;
			}
			
			int x = Stage.GetPixelsX(e.X, this.picStage.Width);
			int y = Stage.GetPixelsY(e.Y, this.picStage.Height);
			
			/*
			 * To prevent the modification of properties
			 */
			if (!this.picStage.Focused
			    && (this.txtPropName.Focused || this.txtX.Focused || this.txtY.Focused || this.txtW.Focused || this.txtH.Focused || this.cboZoom.Focused || this.treeLibrary.Focused))
			{
			    this.picStage.Focus();
			}

			/*
			 * Show our position
			 */
			this.tipPos.Text = "x: " + x + " y: " + y;
			
			/*
			 * Drag the stage
			 */
			if (e.Button == MouseButtons.Right)
			{
			    if (DragType == DRAG_STAGE)
			    {
			        int dx = e.X - DragOX;
			        int dy = e.Y - DragOY;
			        
			        Stage.ox += dx;
			        Stage.oy += dy;
			        
			        DragOX = e.X;
			        DragOY = e.Y;
			    }
			}
			
			/*
			 * EDIT_CLIP_BITMAP
			 */
			if (EditType == EDIT_CLIP_BITMAP)
			{
    			if (e.Button == MouseButtons.Left)
    			{
        			if (libEdit == null)
        			{
        				return;
        			}
        
        			if (DragType == DRAG_ALL)
        			{
        				((Clip)libEdit.Tag).r.X = x - DragOX;
        				((Clip)libEdit.Tag).r.Y = y - DragOY;
        			}
        			else if (DragType == DRAG_LEFT)
        			{
        				int dx = x - DragOX;
        				((Clip)libEdit.Tag).r.X = x;
        				((Clip)libEdit.Tag).r.Width = DragTemp - dx;
        			}
        			else if (DragType == DRAG_RIGHT)
        			{
        				int dx = x - DragOX;
        				((Clip)libEdit.Tag).r.Width = DragTemp + dx;
        			}
        			else if (DragType == DRAG_UP)
        			{
        				int dy = y - DragOY;
        				((Clip)libEdit.Tag).r.Y = y;
        				((Clip)libEdit.Tag).r.Height = DragTemp - dy;
        			}
        			else if (DragType == DRAG_DOWN)
        			{
        				int dy = y - DragOY;
        				((Clip)libEdit.Tag).r.Height = DragTemp + dy;
        			}
    			}
			}
			/*
			 * EDIT_CLIP_STATIC
			 */
			else if (EditType == EDIT_CLIP_STATIC)
			{
			    if (EditClip != -1)
			    {
			        Clip _clip = ((Clip)libEdit.Tag);
			        _clip.childs[EditClip].x = x - DragOX;
                    _clip.childs[EditClip].y = y - DragOY;
			    }
			}
			/*
			 * EDIT_CLIP_ANIMATION
			 */
			else if (EditType == EDIT_CLIP_ANIMATION)
			{
			    if (EditClip != -1)
			    {
			        Clip _clip = ((Clip)libEdit.Tag);
			        _clip.childs[EditClip].x = x - DragOX;
                    _clip.childs[EditClip].y = y - DragOY;
			    }
			}
			
			if (DragType != DRAG_NONE)
			{
				this.picStage.Invalidate();
			}
		}
		
		/*
		 * PicStageMouseUp
		 */
		void PicStage_MouseUp (object sender, MouseEventArgs e)
		{
			if (libEdit == null)
			{
				return;
			}
			
			((Clip)libEdit.Tag).AdjustSize();
			
			if (EditType == EDIT_CLIP_BITMAP)
			{
			    if (DragType != DRAG_NONE)
			    {
			        this.txtX.Text = ((Clip)libEdit.Tag).r.X.ToString();
			        this.txtY.Text = ((Clip)libEdit.Tag).r.Y.ToString();
			        this.txtW.Text = ((Clip)libEdit.Tag).r.Width.ToString();
			        this.txtH.Text = ((Clip)libEdit.Tag).r.Height.ToString();
			        
			        this.txtX.Invalidate();
			        this.txtY.Invalidate();
			        this.txtW.Invalidate();
			        this.txtH.Invalidate();
			        
			        this.picPreview.Invalidate();
			    }
			}
			else if (EditType == EDIT_CLIP_STATIC)
			{
			    if (DragType != DRAG_NONE)
			    {
			        this.txtX.Text = ((Clip)libEdit.Tag).r.X.ToString();
			        this.txtY.Text = ((Clip)libEdit.Tag).r.Y.ToString();
			        this.txtW.Text = ((Clip)libEdit.Tag).r.Width.ToString();
			        this.txtH.Text = ((Clip)libEdit.Tag).r.Height.ToString();
			        
			        this.txtX.Invalidate();
			        this.txtY.Invalidate();
			        this.txtW.Invalidate();
			        this.txtH.Invalidate();
			        
			        this.picPreview.Invalidate();
			    }
			}
			
			DragType = DRAG_NONE;
			EditClip = -1;
			this.picStage.Cursor = System.Windows.Forms.Cursors.Default;
		}
		
		/*
		 * PicStage_DragOver
		 */
		void PicStage_DragOver (object sender, System.Windows.Forms.DragEventArgs e)
		{
		    if (libEdit == null)
		    {
		        e.Effect = System.Windows.Forms.DragDropEffects.None;
		    }
		    else
		    {
                e.Effect = System.Windows.Forms.DragDropEffects.Move;
		    }
		}
		
		/*
		 * PicStage_DragEnter
		 */
		void PicStage_DragEnter (object sender, System.Windows.Forms.DragEventArgs e)
		{
		    if (libEdit == null)
		    {
		        e.Effect = System.Windows.Forms.DragDropEffects.None;
		    }
		    else
		    {
                e.Effect = System.Windows.Forms.DragDropEffects.Move;
		    }
		}
		
		/*
		 * PicStage_DragDrop
		 */
		void PicStage_DragDrop (object sender, System.Windows.Forms.DragEventArgs e)
		{
		    Utils.Trace("Stage Drop");
		    
		    if (libEdit == null)
		    {
		        e.Effect = System.Windows.Forms.DragDropEffects.None;
		    }
		    else
		    {
		        Point p = this.picStage.PointToClient(new Point(e.X, e.Y));
		        
		        int x = Stage.GetPixelsX(p.X, this.picStage.Width);
			    int y = Stage.GetPixelsY(p.Y, this.picStage.Height);
			    
			    e.Effect = System.Windows.Forms.DragDropEffects.Move;
                
                Clip _clip = ((Clip)libEdit.Tag);
                Clip _clip_to_add = ((Clip)libDragDrop.Tag);
    		    
                AppendClip(_clip, _clip_to_add, x, y);
		    }
		}
		
		/*
		 * Library Click
		 */
		void TreeLibrary_AfterSelect(object sender, TreeViewEventArgs e)
		{
			string strkey = e.Node.Name.ToString();
			
			if (strkey.IndexOf("_clip") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_clip;
			}
			else if (strkey.IndexOf("_library") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_lib;
			}
			
			if (strkey.IndexOf("_bitmap_source") != -1)
			{
				e.Node.ContextMenuStrip = this.contextLibrary_bitmap;
			}
			else
			{
				libSel = e.Node;
				
				if (libEdit == null)
				{
				    this.insertToolStripMenuItem.Visible = false;
				}
				else if (((Clip)libEdit.Tag).usebitmap)
				{
				    this.insertToolStripMenuItem.Visible = false;
				}
				else
				{
				    if (libSel != libEdit)
				    {
				        this.insertToolStripMenuItem.Visible = true;
				    }
				    else
				    {
				        this.insertToolStripMenuItem.Visible = false;
				    }
				}
				
				this.picPreview.Invalidate();
			}
		}
		
		/*
		 * TreeLibrary_DoubleClick
		 */
		void TreeLibrary_DoubleClick (object sender, EventArgs e)
		{
		    EditToolStripMenuItem1Click(this, e);
		}
		
		/*
		 * TreeLibrary_ItemDrag
		 */
		void TreeLibrary_ItemDrag (object sender, System.Windows.Forms.ItemDragEventArgs e)
		{
		    libDragDrop = (TreeNode)e.Item;
		    libSel = libDragDrop;
		    this.picPreview.Invalidate();
		    this.DoDragDrop("1", System.Windows.Forms.DragDropEffects.Move);
		}
		
		/*
		 * Context/Library/Bitmap/Set source bitmap...
		 */
		void SetSourceImageToolStripMenuItem1Click(object sender, EventArgs e)
		{
			SetSourceImageToolStripMenuItemClick(sender, e);
		}
		
		/*
		 * Context/Library/Clip/Add...
		 */
		void AddClipToolStripMenuItemClick(object sender, EventArgs e)
		{
			nc = new NewClip();
		}

		/*
		 * Context/Library/Clip/Insert
		 */
		void InsertToolStripMenuItemClick(object sender, EventArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
		    Clip _clip = ((Clip)libEdit.Tag);
		    Clip _clip_to_add = ((Clip)libSel.Tag);
		    
		    AppendClip(_clip, _clip_to_add, 0, 0);
		}
		
		/*
		 * Context/Library/Clip/Edit
		 */
		void EditToolStripMenuItem1Click(object sender, EventArgs e)
		{
			libEdit = libSel;
			this.tcStage.Enabled = true;
			this.timeLine.Visible = true;
			this.txtPropName.Text = libSel.Text;
			this.lblClipName.Text = Workspace.CLIP_NAME_NAME + libSel.Text;
			
			if (((Clip)libEdit.Tag).usebitmap)
			{
			    this.timeLine.Visible = false;
			    EditType = EDIT_CLIP_BITMAP;
			    this.tcStage.SelectedIndex = 0;
			}
			else if (((Clip)libEdit.Tag).type == Workspace.TYPE_CLIP)
			{
			    EditType = EDIT_CLIP_STATIC;
			    this.tcStage.SelectedIndex = 1;
			    this.timeLine.guide_max = 0;
			}
			else if (((Clip)libEdit.Tag).type == Workspace.TYPE_ANIMCLIP)
			{
			    EditType = EDIT_CLIP_ANIMATION;
			    this.tcStage.SelectedIndex = 1;
			    this.timeLine.guide_max = TimeLine.MAX_KEYFRAMES;
			}
			else
			{
			    EditType = EDIT_NONE;
			}
			
			this.txtX.Text = ((Clip)libSel.Tag).r.X.ToString();
			this.txtY.Text = ((Clip)libSel.Tag).r.Y.ToString();
			this.txtW.Text = ((Clip)libSel.Tag).r.Width.ToString();
			this.txtH.Text = ((Clip)libSel.Tag).r.Height.ToString();
			
			PropertiesShow(true);
			
			this.picStage.Invalidate();
			if (EditType != EDIT_NONE
            && this.timeLine.Visible)
			{
			    UpdateCurrentEditClip((Clip)libEdit.Tag);
			}
		}
		
		/*
		 * Cbo/Zoom
		 */
		void CboZoomSelectedIndexChanged(object sender, EventArgs e)
		{
			int zoom = int.Parse(this.cboZoom.Text.Trim('%').Trim());
			
			if (zoom < 100)
			{
				this.cboZoom.Text = "100%";
				return;
			}
			else if (zoom > 1000)
			{
				this.cboZoom.Text = "1000%";
				return;
			}
			
			Stage.zoom = zoom / 100;
			this.picStage.Invalidate();
		}
		
		/*
		 * TimeLine_LayerDelete
		 */
		void TimeLine_LayerDelete (object sender, LayerArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
		    Clip _clip = ((Clip)libEdit.Tag);
		    
		    _clip.childs.RemoveAt(e.layer);
		    UpdateCurrentEditClip(_clip);
		}
		
		/*
		 * TimeLine_KeyframeInsert
		 */
		void TimeLine_KeyframeInsert (object sender, KeyframeArgs e)
		{
			// TODO: more customize options for users.
		}

		/*
		 * TimeLine_GuideChange
		 */
		void TimeLine_GuideChange (object sender, int newpos)
		{
			this.picStage.Invalidate();
		}

		/*
		 * Name changed
		 */
		void TxtPropNameTextChanged(object sender, EventArgs e)
		{
			libEdit.Text = this.txtPropName.Text;
			((Clip)libEdit.Tag).name = this.txtPropName.Text;
			this.lblClipName.Text = Workspace.CLIP_NAME_NAME + this.txtPropName.Text;
			
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
			this.treeLibrary.Invalidate();
		}
		
		/*
		 * X changed
		 */
		void TxtXTextChanged(object sender, EventArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
			int value = Utils.String2Int(this.txtX.Text);
			this.txtX.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.X = value;
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
		}
		
		/*
		 * Y changed
		 */
		void TxtYTextChanged(object sender, EventArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
			int value = Utils.String2Int(this.txtY.Text);
			this.txtY.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Y = value;
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
		}
		
		/*
		 * W changed
		 */
		void TxtWTextChanged(object sender, EventArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
			int value = Utils.String2Int(this.txtW.Text);
			this.txtW.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Width = value;
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
		}
		
		/*
		 * H changed
		 */
		void TxtHTextChanged(object sender, EventArgs e)
		{
		    if (libEdit == null)
		    {
		        return;
		    }
		    
			int value = Utils.String2Int(this.txtH.Text);
			this.txtH.Text = value.ToString();
			
			((Clip)libEdit.Tag).r.Height = value;
			this.picStage.Invalidate();
			this.picPreview.Invalidate();
		}
	}
}
